package com.grape.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.grape.domain.AccountBook;
import com.grape.mapper.AccountBookMapper;
import com.grape.service.IAccountBookService;
import com.grape.service.ICategoryService;
import com.grape.constants.Constants;
import com.grape.error.BusinessException;
import com.grape.utils.StringUtils;
import com.grape.utils.ThreadLocalUtil;
import com.grape.vo.BaseVo;
import com.grape.wrapper.BaseWrapper;
import lombok.AllArgsConstructor;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.MessageFormat;
import java.util.List;

/**
 *
 * 账本表 服务实现类
 *
 * @author      putao
 * @email       2628279194@qq.com
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class AccountBookServiceImpl extends ServiceImpl<AccountBookMapper, AccountBook> implements IAccountBookService {

    private final AccountBookMapper accountBookMapper;

    private final ICategoryService categoryService;

    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(AccountBookServiceImpl.class);

    /**
     * 分页
     * @param baseVo    统一分页对象
     * @return          账本表集合
     */
    @Override
    public List<AccountBook> listData(BaseVo baseVo) {
        QueryWrapper<AccountBook> wrapper = new BaseWrapper<AccountBook>().init();
        wrapper.like(Strings.isNotBlank(baseVo.getSearch()), Constants.NAME, baseVo.getSearch())
                .eq(StringUtils.isNotBlank(baseVo.getColumnName()) && StringUtils.isNotBlank(baseVo.getSelect()), baseVo.getColumnName(), baseVo.getSelect());
        orderByModifyTimeDesc(wrapper);
        return this.list(wrapper);
    }

    /**
     * 自定义分页
     * @param   baseVo      统一分页对象
     */
    @Override
    public void pageListCustom(BaseVo baseVo) {
        String userId = ThreadLocalUtil.getUserId();
        QueryWrapper<AccountBook> qw = new QueryWrapper<AccountBook>().eq(Constants.USER_ID, userId)
                .orderByDesc(Constants.CREATE_TIME);
        this.accountBookMapper.selectList(qw);
    }

    /**
     * 修改
     * @param accountBook 账本表对象
     */
    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public void updateData(AccountBook accountBook) {
        this.baseUpdate(accountBook);
    }

    /**
     * 新增
     * @param       accountBook 账本表对象
     * @return      账本表对象
     */
    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public AccountBook insertData(AccountBook accountBook) {
        // TODO 判断是否为会员，不是会员只能保存一个账本
        accountBook.setTotalNum(0);
        accountBook.setUserId(ThreadLocalUtil.getUserId());
        this.checkIsRepeat(null, accountBook, Constants.NAME, MessageFormat.format("账本名字：{0} 已存在", accountBook.getName()));
        return this.baseInsert(accountBook);
    }

    /**
     * 删除
     * @param id    单据id
     * @return      删除条数
     */
    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public int deleteData(String id) {
        List<AccountBook> bookList = this.list(new BaseWrapper<AccountBook>().initDelFlagAndUserId(ThreadLocalUtil.getUserId()).ne(Constants.ID, id));
        if (CollectionUtil.isEmpty(bookList)) {
            throw new BusinessException("至少保留一个账本");
        }
        return this.baseDelete(id);
    }

    /**
     * 根据id查询详情
     * @param       id  单据id
     * @return      账本表对象
     */
    @Override
    public AccountBook detail(String id) {
        return this.getByIdForDelFlag(id);
    }

    /**
     * 查询当前用户全部账本
     * @return 账本列表
     */
    @Override
    public List<AccountBook> listAll() {
        return accountBookMapper.selectList(new BaseWrapper<AccountBook>().initDelFlagAndUserId());
    }

    /**
     * 初始化账本数据
     * @param userId  用户id
     * @return 账本对象
     */
    @Override
    public void insertDefaultData(String userId) {
        AccountBook accountBook = new AccountBook();
        accountBook.setName(Constants.ACCOUNT_BOOK_DEFAULT_NAME);
        accountBook.setTotalNum(0);
        accountBook.insertInitByUseId(userId);
        this.save(accountBook);
        categoryService.insertDefaultData(accountBook, userId);
    }
}
